<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8'/>
    <title>Drive</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no'/>
    <link rel="icon" href="favicon.ico">
    <link rel="stylesheet" href="../node_modules/mapbox-gl/dist/mapbox-gl.css">
    <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.css">
    <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap-theme.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/threebox.js" type="text/javascript"></script>
    <script src="js/config.js"></script>
    <script src="../node_modules/mapbox-gl/dist/mapbox-gl.js"></script>
    <script src="../node_modules/jquery/dist/jquery.js"></script>
    <script src="../node_modules/socket.io-client/dist/socket.io.js"></script>
    <script src="../node_modules/bootstrap/dist/js/bootstrap.js"></script>
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }

    </style>
</head>

<body>

<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
    <a class="navbar-brand" href="#">环境对象统一标识平台</a>

    <div class="collapse navbar-collapse" id="navbar-collapse-basepage">
        <ul class="nav navbar-nav">
            <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">连接 <span class="caret"></span></a>
                <ul class="dropdown-menu" role="menu">
                    <li><a href="#" id="li_car_1">Car 1</a></li>
                    <li><a href="#">Car 2</a></li>
                    <li><a href="#">Car 3</a></li>
                </ul>
            </li>
            <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">地图 <span class="caret"></span></a>
                <ul class="dropdown-menu" role="menu">
                    <li><a href="#" id="li_2d_map">2D</a></li>
                    <li><a href="#" id="li_3d_map">3D</a></li>
                </ul>
            </li>
            <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">跟踪 <span class="caret"></span></a>
                <ul class="dropdown-menu" role="menu">
                    <li><a href="#" id="li_trace_open">打开</a></li>
                    <li><a href="#" id="li_trace_close">关闭</a></li>
                </ul>
            </li>
            <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">网格 <span class="caret"></span></a>
                <ul class="dropdown-menu" role="menu">
                    <li><a href="#" id="li_grid_open">打开</a></li>
                    <li><a href="#" id="li_grid_close">关闭</a></li>
                </ul>
            </li>
            <li><a href="#" class="click_pop">UCL</a></li>
        </ul>
    </div>

</nav>

<div id='map'></div>

<div id="pop" class="pop">
    <div class="pop-top">
        <button style="border-radius: 5px; cursor: pointer; color: #1f6377" class="pop-text-add">Add Data</button>
    </div>
    <ul class="pop-content">
    </ul>
    <div class="pop-foot">
        <input type="button" value="Clean" class="pop-clean">
        <input type="button" value="Close" class="pop-cancel">
    </div>
</div>
<script>
    mapboxgl.accessToken = 'pk.eyJ1Ijoidml2aWVuZmFuZ2h1YSIsImEiOiJjaWdycTdwbmowMjB0dHBrbjZxb2xwczdxIn0.--jl_1q3BCW1OYOqM7QBsw';
    var map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/vivienfanghua/cjewdaxtt1r012tnxll9ia825',
        center: [116.3205, 39.99841],
        pitch: 45,
        heading: 0,
        hash: true,
        zoom: 18
    });
    map.addControl(new mapboxgl.NavigationControl(), 'bottom-right');

    var is_3d = false;
    var is_tracing = true;
    var lastTime = new Date();
    var line_geojson = {
        "type": "FeatureCollection",
        "features": [{
            "type": "Feature",
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [116.30806, 39.98534]
                ]
            }
        }]
    };

    var car_source = {
        type: "FeatureCollection",
        features: [
            {
                type: "Feature",
                properties: {
                    heading: 30,
                    scale: 10
                },
                geometry: {type: "Point", coordinates: [0, 0]}
            }
        ]
    };

    var Truck_source = {
        type: "FeatureCollection",
        features: [{
            type: "Feature",
            properties: {
                heading: 30,
                scale: 10
            },
            geometry: {type: "Point", coordinates: [116.32192, 39.99972]}
        }, {
            type: "Feature",
            properties: {
                heading: 30,
                scale: 10
            },
            geometry: {type: "Point", coordinates: [116.32165, 40.00333]}
        }, {
            type: "Feature",
            properties: {
                heading: 30,
                scale: 10
            },
            geometry: {type: "Point", coordinates: [116.32706, 39.99938]}
        },
            {
                type: "Feature",
                properties: {
                    heading: 30,
                    scale: 10
                },
                geometry: {type: "Point", coordinates: [116.32631,39.99917]}
            }
        ]
    };

    var Man_source = {
        type: "FeatureCollection",
        features: [{
            type: "Feature",
            properties: {
                heading: 30,
                scale: 10
            },
            geometry: {type: "Point", coordinates: [116.32, 39.997]}
        }, {
            type: "Feature",
            properties: {
                heading: 30,
                scale: 10
            },
            geometry: {type: "Point", coordinates: [116.316, 39.999]}
        },
            {
                type: "Feature",
                properties: {
                    heading: 30,
                    scale: 10
                },
                geometry: {type: "Point", coordinates: [116.317, 39.999]}
            },
            {
                type: "Feature",
                properties: {
                    heading: 30,
                    scale: 10
                },
                geometry: {type: "Point", coordinates: [116.315, 39.998]}
            },
            {
                type: "Feature",
                properties: {
                    heading: 30,
                    scale: 10
                },
                geometry: {type: "Point", coordinates: [116.314, 39.996]}
            },
            {
                type: "Feature",
                properties: {
                    heading: 30,
                    scale: 10
                },
                geometry: {type: "Point", coordinates: [116.317, 39.994]}
            }
        ]
    };

    var building_source = {
        type: "FeatureCollection",
        features: [
            {
                type: "Feature",
                properties: {
                    heading: 30,
                    scale: 10
                },
                geometry: {type: "Point", coordinates: [116.3206, 40.05165]}
            }
        ]
    };

    var near_grid_json = {
        'type': 'FeatureCollection',
        'features': []
    };

    var very_near_grid_json = {
        'type': 'FeatureCollection',
        'features': []
    };

    var start_X = 116.31;
    var start_Y = 39.99;
    var delta_X_very_near = 0.00002;
    var delta_Y_very_near = 0.00002;
    var delta_X_near = 0.00004;
    var delta_Y_near = 0.00004;
    var near_dict = {};
    var very_near_dict = {};
    var grid_layer_list = [];
    var symbols_truck, symbols_man, symbols_building, symbol_car;

    var socket = io();

    function create_3d(threebox, X, Y, Z, geometry, material) {
        /*var geometry = new THREE.BoxGeometry(4, 4, 4);
         var redMaterial = new THREE.MeshPhongMaterial({color: 0xffaaaa, side: THREE.DoubleSide});*/
        var cube = new THREE.Mesh(geometry, material);
        cube.userData.name = "Red cube";
        threebox.addAtCoordinate(cube, [X, Y, Z], {preScale: 1});
    }

    function change_grid_color(x, y) {
        var very_near_code_X = Math.floor((x - start_X) / delta_X_very_near);
        var very_near_code_Y = Math.floor((y - start_Y) / delta_Y_very_near);
        var near_code_X = Math.floor((x - start_X) / delta_X_near);
        var near_code_Y = Math.floor((y - start_Y) / delta_Y_near);
        var x_grid_very_near = very_near_code_X * delta_X_very_near + start_X - delta_X_very_near;
        var y_grid_very_near = very_near_code_Y * delta_Y_very_near + start_Y - delta_Y_very_near;
        var x_grid_near = near_code_X * delta_X_near + start_X - delta_X_near;
        var y_grid_near = near_code_Y * delta_Y_near + start_Y - delta_Y_near;
        if (!very_near_dict[very_near_code_X + '-' + very_near_code_Y]) {
            very_near_grid_json.features.push(
                {
                    'type': 'Feature',
                    'geometry': {
                        'type': 'Polygon',
                        'coordinates': [
                            [
                                [x_grid_very_near, y_grid_very_near],
                                [x_grid_very_near + 2 * delta_X_very_near, y_grid_very_near],
                                [x_grid_very_near + 2 * delta_X_very_near, y_grid_very_near + 2 * delta_Y_very_near],
                                [x_grid_very_near, y_grid_very_near + 2 * delta_Y_very_near],
                                [x_grid_very_near, y_grid_very_near]
                            ]
                        ]
                    }
                }
            );
            very_near_dict[very_near_code_X + '-' + very_near_code_Y] = true;
        }
        if (!near_dict[near_code_X + '-' + near_code_Y]) {
            near_grid_json.features.push(
                {
                    'type': 'Feature',
                    'geometry': {
                        'type': 'Polygon',
                        'coordinates': [
                            [
                                [x_grid_near, y_grid_near],
                                [x_grid_near + 2 * delta_X_near, y_grid_near],
                                [x_grid_near + 2 * delta_X_near, y_grid_near + 2 * delta_Y_near],
                                [x_grid_near, y_grid_near + 2 * delta_Y_near],
                                [x_grid_near, y_grid_near]
                            ]
                        ]
                    }
                }
            );
            near_dict[near_code_X + '-' + near_code_Y] = true;
        }
    }

    function add_ucl(content, size) {
        var dateObj = new Date();
        var year = dateObj.getFullYear();//年
        var month = dateObj.getMonth() + 1;//月(注意：月份+1)
        var date = dateObj.getDate();//日
        var hours = dateObj.getHours();//小时
        var minutes = dateObj.getMinutes();//分钟
        var seconds = dateObj.getSeconds();//秒
        if (month < 10) {
            month = "0" + month;
        }
        if (date < 10) {
            date = "0" + date;
        }
        if (hours < 10) {
            hours = "0" + hours;
        }
        if (minutes < 10) {
            minutes = "0" + minutes;
        }
        if (seconds < 10) {
            seconds = "0" + seconds;
        }
        var newDate = year + "年" + month + "月" + date + "日" + hours + ":" + minutes + ":" + seconds;
        $(".pop-content").prepend("<li>" + content + "</li>");
        $(".pop-content").prepend("<li>" + newDate + "&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp" + size + "KB" + "</li>");
    }

    map.on('load', function () {

        window.threebox = new Threebox(map);
        threebox.setupDefaultLights();
        symbols_building = threebox.addSymbolLayer({
            id: "building",
            source: building_source,
            modelName: "test02",    // will look for an .obj and .mtl file with this name
            modelDirectory: "models/",          // in this directory
            rotation: new THREE.Euler(0, 0, 0.5 * Math.PI, "XYZ"),
            scale: 1,
            scaleWithMapProjection: true,
            key: {property: "id"}
        });

        symbols_truck = threebox.addSymbolLayer({
            id: "trucks",
            source: Truck_source,
            modelName: "Truck",    // will look for an .obj and .mtl file with this name
            modelDirectory: "models/",
            rotation: new THREE.Euler(0.5 * Math.PI, 0.5 * Math.PI, 0, "XYZ"),
            scale: 5
        });

        symbols_man = threebox.addSymbolLayer({
            id: "man",
            source: Man_source,
            modelName: "man",    // will look for an .obj and .mtl file with this name
            modelDirectory: "models/",
            rotation: new THREE.Euler(0.5 * Math.PI, 0.5 * Math.PI, 0, "XYZ"),
            scale: 0.1
        });

        symbol_car = threebox.addSymbolLayer({
            id: "car",
            source: car_source,
            modelName: "car",    // will look for an .obj and .mtl file with this name
            modelDirectory: "models/",
            rotation: new THREE.Euler(0.5 * Math.PI, 0.5 * Math.PI, 0, "XYZ"),
            scale: 0.05
        });

        var man_three_geometry = new THREE.BoxGeometry(10, 10, 20);
        var truck_three_geometry = new THREE.BoxGeometry(20, 20, 20);

        var three_material = new THREE.MeshPhongMaterial({
            color: 0xffaaaa,
            side: THREE.DoubleSide,
            transparent: true,
            opacity: 0.4
        });
        for (i = 0; i < Man_source.features.length; i++) {
            feature = Man_source.features[i];
            coords = feature.geometry.coordinates;
            create_3d(threebox, coords[0] - 0.00005, coords[1] - 0.00001, 0, man_three_geometry, three_material);
        }
        for (i = 0; i < Truck_source.features.length; i++) {
            feature = Truck_source.features[i];
            coords = feature.geometry.coordinates;
            create_3d(threebox, coords[0], coords[1] - 0.000005, 0, truck_three_geometry, three_material);
        }

        grid_layer_list.push(map.getLayer('grid-4'));
        grid_layer_list.push(map.getLayer('grid-3'));
        grid_layer_list.push(map.getLayer('grid-2'));
        grid_layer_list.push(map.getLayer('grid-1'));
        grid_layer_list[0].minZoom = 13;
        grid_layer_list[0].maxZoom = 15;
        grid_layer_list[1].minZoom = 15;
        grid_layer_list[1].maxZoom = 17;
        grid_layer_list[2].minZoom = 17;
        grid_layer_list[2].maxZoom = 19;
        grid_layer_list[3].minZoom = 19;

        map.addLayer({
            'id': 'line-animation',
            'type': 'line',
            'source': {
                'type': 'geojson',
                'data': line_geojson
            },
            'layout': {
                'line-cap': 'round',
                'line-join': 'round'
            },
            'paint': {
                'line-color': '#ed6498',
                'line-width': 5,
                'line-opacity': .8
            }
        });
        map.addSource('car', {type: 'geojson', data: car_source});
        // map.addSource('grid', {type: 'geojson', data: total_grid_json});
        map.addSource('near', {type: 'geojson', data: near_grid_json});
        map.addSource('very-near', {type: 'geojson', data: very_near_grid_json});
        map.addLayer({
            "id": "car-marker",
            "type": "symbol",
            "source": "car",
            "layout": {
                "icon-image": "circle-15",
                "icon-rotation-alignment": "map"
            }
        });


        map.addLayer({
            'id': 'near-layer',
            'type': 'fill',
            'source': "near",
            'layout': {},
            'paint': {
                'fill-outline-color': "#cfcfcf",
                'fill-color': "#e7dc7b",
                'fill-opacity': 0.8
            }
        });

        map.addLayer({
            'id': 'very-near-layer',
            'type': 'fill',
            'source': "very-near",
            'layout': {},
            'paint': {
                'fill-outline-color': "#cfcfcf",
                'fill-color': "#e70016",
                'fill-opacity': 0.8
            }
        });

        line_geojson.features[0].geometry.coordinates.pop();

        map.on('click', 'grid-1', function (e) {
            if ($('.mapboxgl-popup').length > 0)
                return;
            new mapboxgl.Popup()
                .setLngLat(e.lngLat)
                .setHTML('层级:20<br>网格码：' + e.features[0].properties.id + '<br>状态：' + e.features[0].properties.type)
                .addTo(map);
            e.originalEvent.stopPropagation();
        });

        map.on('click', 'grid-2', function (e) {
            if ($('.mapboxgl-popup').length > 0)
                return;
            new mapboxgl.Popup()
                .setLngLat(e.lngLat)
                .setHTML('层级:19<br>网格码：' + e.features[0].properties.id + '<br>状态：' + e.features[0].properties.type)
                .addTo(map);
            e.originalEvent.stopPropagation();
        });

        map.on('click', 'grid-3', function (e) {
            if ($('.mapboxgl-popup').length > 0)
                return;
            new mapboxgl.Popup()
                .setLngLat(e.lngLat)
                .setHTML('层级:18<br>网格码：' + e.features[0].properties.id + '<br>状态：' + e.features[0].properties.type)
                .addTo(map);
            e.originalEvent.stopPropagation();
        });

        map.on('click', 'grid-4', function (e) {
            if ($('.mapboxgl-popup').length > 0)
                return;
            new mapboxgl.Popup()
                .setLngLat(e.lngLat)
                .setHTML('层级:17<br>网格码：' + e.features[0].properties.id + '<br>状态：' + e.features[0].properties.type)
                .addTo(map);
            e.originalEvent.stopPropagation();
        });

        map.on('click', 'near', function (e) {
            if ($('.mapboxgl-popup').length > 0)
                return;
            new mapboxgl.Popup()
                .setLngLat(e.lngLat)
                .setHTML('障碍物类别:行人<br>网格码：' + Math.floor(Math.random()*1000000) + '<br>状态：警告')
                .addTo(map);
            e.originalEvent.stopPropagation();
        });

        map.on('click', 'very-near', function (e) {
            if ($('.mapboxgl-popup').length > 0)
                return;
            new mapboxgl.Popup()
                .setLngLat(e.lngLat)
                .setHTML('障碍物类别:行人<br>网格码：' + Math.floor(Math.random()*1000000) + '<br>状态：危险')
                .addTo(map);
            e.originalEvent.stopPropagation();
        });

        socket.on('record', function (data) {
            if (!data.message)
                return;
            var messageList = data.message.split(",");
            for (var i in messageList) {
                var message = messageList[i];
                var columns = message.split(" ").map(function (e) {
                    return parseFloat(e);
                });

                var location = [columns[1], columns[2]];
                //不规范经纬度跳过
                if (location[0] < 1 || location[1] < 1)
                    continue;
                car_source.features[0].geometry.coordinates = location;
                line_geojson.features[0].geometry.coordinates.push(location);
                // map.getSource('car').setData(car_source);
                symbol_car.updateSourceData(car_source);
            }
            map.getSource('line-animation').setData(line_geojson);

            var currentTime = new Date();
            if (currentTime - lastTime > 2000) {
                if (is_tracing) {
                    if (Math.abs(map.getCenter().lat - location[1]) >= 0.0002 ||
                        Math.abs(map.getCenter().lng - location[2]) >= 0.0002) {
                        map.setCenter(location);
                    }
                }
                lastTime = currentTime;
            }
        });

        socket.on('barrier', function (data) {

            if (!data.message)
                return;
            var messageList = data.message.split(",");
            for (var i in messageList) {
                var message = messageList[i];
                var columns = message.split(" ").map(function (e) {
                    return parseFloat(e);
                });
                // 不规范经纬度跳过
                if (columns[1] < 1 || columns[2] < 1)
                    continue;
                var feature = {
                    type: "Feature",
                    properties: {
                        heading: 30,
                        scale: 10
                    },
                    geometry: {type: "Point", coordinates: [columns[1], columns[2]]}
                };
                Man_source.features.push(feature);
                create_3d(threebox, columns[1] - 0.00005, columns[2] - 0.00001, 0, man_three_geometry, three_material);
                symbols_man.updateSourceData(Man_source);
                change_grid_color(columns[1], columns[2]);
                map.getSource('near').setData(near_grid_json);
                map.getSource('very-near').setData(very_near_grid_json);
            }

        });

        socket.on('reset', function (data) {
            line_geojson.features[0].geometry.coordinates = [];
            time_index_pair = {};
        });

        socket.on('ucl', function (data) {
            if (!data.message)
                return;
            var columns = data.message.split(',');
            var size = parseFloat(columns[1]);
            var content = columns[2];
            add_ucl(content, size);
        });

    });

    $(document).ready(function () {
        $("#li_2d_map").click(function () {
            map.setPitch(0);
            is_3d = false;
        });
        $("#li_3d_map").click(function () {
            map.setPitch(60);
            is_3d = true;
        });

        $("#li_trace_open").click(function () {
            is_tracing = true;
        });
        $("#li_trace_close").click(function () {
            is_tracing = false;
            map.setBearing(0);
            map.setPitch(0);
        });

        $("#li_grid_open").click(function () {
            for (var i in grid_layer_list) {
                grid_layer_list[i].setLayoutProperty('visibility', 'visible')
            }
        });
        $("#li_grid_close").click(function () {
            for (var i in grid_layer_list) {
                grid_layer_list[i].setLayoutProperty('visibility', 'none')
            }
        });

        $("#li_car_1").click(function () {
            car_source.features.pop();

            var feature = {
                type: "Feature",
                properties: {
                    heading: 30,
                    scale: 10
                },
                geometry: {type: "Point", coordinates: [116.32647, 39.99927]}
            };
            car_source.features.push(feature);
            symbol_car.updateSourceData(car_source);
        });

        $('.pop-cancel').click(function () {
            $('.pop').hide();
        });

        $('.pop-clean').click(function () {
            $('.pop-content').html("");
        });

        $('.click_pop').click(function () {
            $('.pop').show();
        });

        $('.pop-text-add').click(function () {
            add_ucl("duiwe2dhdhuasicbkjsnduiehdiajcnklajndashdfbuihupsodkasop", 0.124);

        });
    });
</script>

</body>

</html>
